package org.hales.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import javax.annotation.Resource;
import java.util.Arrays;


@Configuration
@EnableWebSecurity
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private LoginSuccessHandler loginSuccessHandler;

    @Autowired
    private LoginFailureHandler loginFailureHandler;
//
//    @Value("${application-referer}")
//    private String iplist;

    @Value("${spring.profiles.active}")
    private String profile;

    @Value("${interceptor-ignoreUris}")
    private String interceptorIgnoreUris;
    @Value("${interceptor-ignoreUris-add}")
    private String interceptorIgnoreUrisAdd;

    @Resource
    private UrlAuthenticationEntryPoint authenticationEntryPoint; //自定义未登录时：返回需要登录

    @Autowired
    private CaptchaFilter captchaFilter;


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        // 未登录时：返回需要登录
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);


        http.formLogin()
            //.loginPage("/authentication/require")//这个页面必须要放在resources/resources里，否则提交不会生效，估计是安全框架的机制
            .loginProcessingUrl("/user/securityLogin.do")//这里的名字和登录页的Post内容一致，就可以调框架自带的登录
            .successHandler(loginSuccessHandler)
            .failureHandler(loginFailureHandler)
            .and()
            .rememberMe()
            //.defaultSuccessUrl("/page/view/index/index.html")
            //.successForwardUrl("success.html")
            //.failureForwardUrl("failure.html")
//              .and() 用到jwt时再放开
//              .sessionManagement()
//              .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers(interceptorIgnoreUris.split(",")).permitAll()
            .antMatchers(interceptorIgnoreUrisAdd.split(",")).permitAll()
            //.antMatchers("/admin/user/login.do","/authentication/require").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .headers().frameOptions().disable()//让frame页面可以正常使用
            .and()
            .csrf().disable();

             http.headers().contentSecurityPolicy("frame-ancestors *");
             //允许跨域白名单
             http.cors().configurationSource(corsConfigurationSource());


        http.addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class);


    }


    //配置全局白名单  用到自定义过滤器可以在这个里添加路径
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
        web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
    }

    @Bean
    public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowSemicolon(true);
        firewall.setAllowUrlEncodedSlash(true);
        firewall.setAllowUrlEncodedPeriod(true);
        firewall.setAllowUrlEncodedPercent(true);
        firewall.setAllowUrlEncodedDoubleSlash(true);
        return firewall;
    }



    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new DecodePwdAuthenticationProvider(myUserDetailsService));
        //auth.userDetailsService(myUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }


    CorsConfigurationSource corsConfigurationSource(){
      //  String[] array = iplist.split(",");
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowedMethods(Arrays.asList("*"));
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));//(Arrays.asList(array));
        corsConfiguration.setMaxAge(3600L);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",corsConfiguration);
        return source;
    }



}
